package com.myzhouye.biz.service;/***
 *                    _ooOoo_
 *                   o8888888o
 *                   88" . "88
 *                   (| -_- |)
 *                    O\ = /O
 *                ____/`---'\____
 *              .   ' \\| |// `.
 *               / \\||| : |||// \
 *             / _||||| -:- |||||- \
 *               | | \\\ - /// | |
 *             | \_| ''\---/'' | |
 *              \ .-\__ `-` ___/-. /
 *           ___`. .' /--.--\ `. . __
 *        ."" '< `.___\_<|>_/___.' >'"".
 *       | | : `- \`.;`\ _ /`;.`/ - ` : | |
 *         \ \ `-. \_ __\ /__ _/ .-` / /
 * ======`-.____`-.___\_____/___.-`____.-'======
 *                    `=---='
 *
 * .............................................
 *          佛祖保佑             永无BUG
 */

/**
 * @program: game01
 * @description: 周期任务执行器
 * @author: 那条蠢鱼
 * @create: 2025-11-11 10:10
 **/

import com.google.common.util.concurrent.AtomicDouble;
import lombok.Getter;
import lombok.Setter;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;

import java.time.Duration;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 周期性任务执行器基类
 * 用于封装周期性操作的通用逻辑，如工厂生产、攻击频率控制、物品采集等
 */
public abstract class PeriodicTaskExecutor {
    @Getter
    private final String taskId;          // 任务唯一标识
    @Getter
    private final String taskName;        // 任务名称
    @Getter
    private final double intervalSeconds; // 基础周期间隔(秒)
    @Getter
    private double acceleration = 0.0;   // 加速系数(0.0~1.0)
    @Getter
    private final AtomicDouble progress = new AtomicDouble(0.0); // 任务进度(0.0~1.0)
    @Getter
    @Setter
    private boolean paused = false;       // 任务是否暂停
    private final AtomicBoolean running = new AtomicBoolean(false); // 任务是否运行中

    @Getter
    private RedisFactoryCacheService redisFactoryCacheService;

    public PeriodicTaskExecutor(String taskId, String taskName, double intervalSeconds, RedisFactoryCacheService redisFactoryCacheService) {
        this.taskId = taskId;
        this.taskName = taskName;
        this.intervalSeconds = intervalSeconds;
        this.redisFactoryCacheService = redisFactoryCacheService;
    }

    /**
     * 启动周期性任务
     */
    public void start() {
        if (running.compareAndSet(false, true)) {
            executePeriodicTask();
        }
    }

    /**
     * 停止周期性任务
     */
    public void stop() {
        running.set(false);
    }

    /**
     * 设置加速系数
     * @param acceleration 加速系数(0.0~1.0)，0.2表示加速20%
     */
    public void setAcceleration(double acceleration) {
        this.acceleration = Math.max(0.0, Math.min(1.0, acceleration));
    }

    /**
     * 执行周期性任务的核心逻辑
     */
    private void executePeriodicTask() {
        Flux.interval(Duration.ofMillis(100)) // 每100ms检查一次
                .subscribeOn(Schedulers.boundedElastic())
                .takeWhile(tick -> running.get())
                .filter(tick -> !paused)
                .subscribe(tick -> {
                    double adjustedInterval = intervalSeconds * (1 - acceleration);
                    double progressIncrement = 0.1 / adjustedInterval; // 基于100ms间隔计算进度增量
                    double newProgress = progress.addAndGet(progressIncrement);

                    if (newProgress >= 1.0) {
                        progress.set(0.0);
                        onTaskComplete(); // 任务周期完成时执行具体业务逻辑
                    }
                });
    }

    /**
     * 任务周期完成时的回调方法，由子类实现具体业务逻辑
     */
    protected abstract void onTaskComplete();
}
